package com.authority.tree;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import com.authority.entry.AuthActionDO;
import com.authority.entry.AuthMenuDO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class NodeUtils {
	
	public static final String ROOT = "0";

	/**
	 * 创建根节点
	 * @return
	 */
	public static Node createRootNode(){
		
		Node root = new Node();
		root.setId(ROOT);
		root.setParentId("");
		root.setText("根节点");
		root.setLeaf(false);
		root.setChecked(false);
		root.setExpanded(true);
		root.setType("root");
		root.setUrl("");
		
		return root;
	}
	
	/**
	 * List<Node>转换成Map<String,Node>
	 * @param nodes
	 * @return
	 */
	public static Map<String,Node> generateNodeMap(List<Node> nodes){
		
		 Map<String,Node> map = Maps.newHashMap();
		for(Node n : nodes){
			map.put(n.getId(), n);
		}
		
		map.put(ROOT, createRootNode());
		
		return map;
	}
	
	/**
	 * 生成节点树
	 * @param map
	 * @param rootId
	 * @return
	 */
	public static Node generateNodeTree(Map<String,Node> map,String rootId){
		
		Node root = map.get(rootId);
		
		 for(String key : map.keySet()){
			 Node node = map.get(key);
			 if(!ROOT.equals(node.getId())){
				 map.get(node.getParentId()).addChild(node);
			 }
		 }
		 
		return root;
	}
	
	
	
	/**
	 * 生成节点树
	 * @param nodes
	 * @param rootId
	 * @return
	 */
	public static Node generateNodeTree(List<Node> nodes,String rootId){
			
		return generateNodeTree(generateNodeMap(nodes),rootId);
	}
	
	/**
	 * 菜单转成节点
	 * @param m
	 * @param isLeaf
	 * @param isChecked
	 * @return
	 */
	public static Node menuToNode(AuthMenuDO m){
		
		Node n = new Node();
		n.setId(m.getId().toString());
		n.setParentId(m.getParentId().toString());
		n.setText(m.getName());
		n.setOrder(m.getNum());
		n.setLeaf(m.getIsLeaf()==1?true:false);
		n.setExpanded(false);
		n.setUrl(m.getUrl());
		n.setType("menu");
		
		return n;
	}
	
	/**
	 * 功能转成节点
	 * @param a
	 * @param menuId
	 * @return
	 */
	public static Node actionToNode(AuthActionDO a,Long menuId,Integer order){
		
		Node n = new Node();
		n.setId(menuId + "_"+ a.getId() +"");
		n.setParentId(menuId.toString());
		n.setText(a.getName());
		n.setOrder(order);
		n.setLeaf(true);
		n.setExpanded(false);
		n.setUrl("");
		n.setType("action");
		
		return n;
	}
	
	
	/**
	 * 菜单列表转节点列表
	 * @param menus 菜单列表
	 * @return 节点列表
	 */
	public static List<Node> menuToNode(List<AuthMenuDO> menus){
		
		List<Node> nodes = Lists.newArrayList();
		
		for(AuthMenuDO m : menus){
			nodes.add(menuToNode(m));
		}
		
		return nodes;
	}
	
	
	/**
	 * 设置树的所有节点为非叶子节点
	 * @param node
	 * @return
	 */
	public static Node setLeaf(Node node){
		
		if(!CollectionUtils.isEmpty(node.getChildren())){
			for(Node n : node.getChildren()){
				setLeaf(n);
			}
		}
		
		node.setLeaf(false);
		
		return node;
	}
	
	/**
	 * 修改指定节点为已选中
	 * @param map
	 * @param id  节点id
	 * @return
	 */
	public static Map<String,Node> checkedNode(Map<String,Node> map,String id){
		
		Node node = map.get(id);
		node.setChecked(true);
		map.put(id, node);
		
		return map;
	}
	
	/**
	 * 对同一层级的节点进行排序(按顺序号) 
	 * @param node
	 * @return
	 */
	 public static Node sortChildren(Node node) { 
		 
		 	List<Node> childs = node.getChildren();
	        if (!CollectionUtils.isEmpty(childs)) {  
	            Collections.sort(childs, new NodeOrderComparator());  
	            for (Node n : childs) {  
	                sortChildren(n);  
	            }  
	        }  
	        
	        return node;
	    }
	 
	 /**
	 * 对同一层级的节点进行排序(指定自定义比较器)
	 * 
	 * @param node
	 * @param c
	 * @return
	 */
	public static Node sortChildren(Node node, Comparator<Node> c) {

		List<Node> childs = node.getChildren();
		if (!CollectionUtils.isEmpty(childs)) {
			Collections.sort(childs, c);
			for (Node n : childs) {
				sortChildren(n, c);
			}
		}

		return node;
	}
	
	public static void main(String[] args) {
		Node node1 = new Node("112000","廊坊银行解放道支行","110000");
			Node node2 = new Node("112200","廊坊银行三大街支行","112000");
			Node node3 = new Node("112100","廊坊银行广阳道支行","112000");
			Node node4 = new Node("113000","廊坊银行开发区支行","110000");
			Node node5 = new Node("100000", "廊坊银行总行","0");
			Node node6 = new Node("110000","廊坊分行","100000");
			Node node7 = new Node("111000","廊坊银行金光道支行","110000");
			
			List<Node> nodes = Lists.newArrayList();
			nodes.add(node1);
			nodes.add(node2);
			nodes.add(node3);
			nodes.add(node4);
			nodes.add(node5);
			nodes.add(node6);
			nodes.add(node7);
			
			Node node = generateNodeTree(nodes,"0");
			System.out.println(node);
			System.out.println(sortChildren(node,new NodeIDComparator()));
			System.out.println(setLeaf(node));
			
	  
	}
}
